package com.minimvc.patterns.facade
{

	import com.minimvc.core.Controller;
	import com.minimvc.core.Model;
	import com.minimvc.core.SimpleEvent;
	import com.minimvc.core.View;
	import com.minimvc.interfaces.IController;
	import com.minimvc.interfaces.IFacade;
	import com.minimvc.interfaces.IMediator;
	import com.minimvc.interfaces.IModel;
	import com.minimvc.interfaces.IProxy;
	import com.minimvc.interfaces.IView;
	
	import flash.events.Event;
	
	/**
	 * 框架外观类,提供框架简洁和更方便的调用;
	 * @author crl
	 * 
	 *  Facade 由于它没有注册的机制 所以它不会引用其它的额外类. 其它类引用它也不会造成内存引用的影响
	   
		facade 在构造函数中使用了instance=this,使得父类会直接引用子类的实现,对于子类特殊需求的重写，也不影响整个框架的运行.

		facade 
				提供注册视图中介与删除视图中介，并在框架内自动触发的产生与注销.
				(
					对于其它视图中介抛出的事件，当前视图中介可以做侦听, 而不用其它的额外的类辅助;
				)
		
				提供注册数据代理与删除数据代理，并在框架内自动触发的产生与注销.
				(
					//todo;
				)
			   
				提供注册命令与删除命令功能, 命令使用无状态与有状态并存的形式.
				(
					无状态: 优点, 运行完成时就全部清理，相当于一个局部变量, 缺点: 重复创建;
					有状态: 跟上面刚好相反;
					
					如何定义有无状态: 看命令触发是否频繁;
				)
	 * 
	 * 
	 */	
	public class Facade implements IFacade
	{
		protected const SINGLETON_MSG	: String = "Facade Singleton already constructed!";
		
		protected var controller : IController;
		protected var model		 : IModel;
		protected var view		 : IView;

		public function Facade( ) {
			if (instance != null) throw Error(SINGLETON_MSG);
			instance = this;
			initializeFacade();	
		}
		
		protected function initializeFacade(  ):void {
			initializeModel();
			initializeController();
			initializeView();
		}
		
		protected static var instance : IFacade; 
		public static function getInstance():IFacade {
			if (instance == null) instance = new Facade( );
			return instance;
		}
		
		
		/**
		 * 初始化命令控制器(没有特殊需求,不建议重写此方法)
		 * 
		 */		
		protected function initializeController( ):void {
			if ( controller != null ) return;
			controller = Controller.getInstance();
		}
		
		/**
		 * 初始化数据代理管理器(没有特殊需求,不建议重写此方法);
		 * 
		 */		
		protected function initializeModel( ):void {
			if ( model != null ) return;
			model = Model.getInstance();
		}
		
		/**
		 * 初始化事件触发器(没有特殊需求,不建议重写此方法); 
		 * 
		 */		
		protected function initializeView( ):void {
			if ( view != null ) return;
			view = View.getInstance();
		}

		/**
		 * 注册事件相关外理器; 
		 * @param eventType
		 * @param commandClassRef
		 * 
		 */		
		public function registerCommand( eventType:String, commandClassRef:Class ):void 
		{
			controller.registerCommand( eventType, commandClassRef );
		}
		
		/**
		 * 删除事件处理器
		 * @param eventType
		 * 
		 */		
		public function removeCommand( eventType:String ):void 
		{
			controller.removeCommand( eventType );
		}
		
		public function hasCommand( eventType:String ) : Boolean
		{
			return controller.hasCommand(eventType);
		}

		public function registerProxy ( proxy:IProxy ):void	
		{
			model.registerProxy ( proxy );	
		}

		public function getProxy ( proxyName:String ):IProxy 
		{
			return model.getProxy ( proxyName );	
		}

		public function removeProxy ( proxyName:String ):IProxy 
		{
			var proxy:IProxy;
			if ( model != null ) proxy = model.removeProxy ( proxyName );	
			return proxy
		}
		
		public function hasProxy( proxyName:String ) : Boolean
		{
			return model.hasProxy( proxyName );
		}
		
		/**
		 *  注册视图中介; 
		 * @param mediator
		 * 
		 */		
		public function registerMediator( mediator:IMediator ):void 
		{
			view.registerMediator( mediator );
		}
		
		/**
		 * 取得视图中介;
		 * @param mediatorName
		 * @return 
		 * 
		 */		
		public function getMediator( mediatorName:String ):IMediator 
		{
			return view.getMediator( mediatorName ) as IMediator;
		}

		public function removeMediator( mediatorName:String ) : IMediator 
		{
			var mediator:IMediator;
			mediator = view.removeMediator( mediatorName );			
			return mediator;
		}

		public function hasMediator( mediatorName:String ) : Boolean
		{
			return view.hasMediator( mediatorName );
		}
		
		/**
		 * 简单派发事件; 
		 * @param type
		 * @param data
		 * @return 
		 * 
		 */		
		public function simpleDispatch(type:String,data:*=null):Boolean{
			return this.dispatchEvent(new SimpleEvent(type,data));
		}
		
		/**
		 * 派发事件,提供自定义事件的派发; 
		 * @param event
		 * @return 
		 * 
		 */		
		public function dispatchEvent ( event:Event):Boolean {
			return view.dispatchEvent( event );
		}
	}
}